package com.itkjb.leisurely.resource.sys.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itkjb.leisurely.core.base.BaseConstants;
import com.itkjb.leisurely.core.base.BaseDto;
import com.itkjb.leisurely.core.base.BaseResult;
import com.itkjb.leisurely.core.base.controller.BaseController;
import com.itkjb.leisurely.core.model.RequestUserInfoModel;
import com.itkjb.leisurely.core.model.SearchModel;
import com.itkjb.leisurely.core.util.QueryUtil;
import com.itkjb.leisurely.core.util.RequestUserInfoUtil;
import com.itkjb.leisurely.resource.common.SysConstants;
import com.itkjb.leisurely.resource.sys.model.SysMenuModel;
import com.itkjb.leisurely.resource.sys.model.SysRoleModel;
import com.itkjb.leisurely.resource.sys.model.vo.SysMenuVO;
import com.itkjb.leisurely.resource.sys.service.ISysMenuService;
import com.itkjb.leisurely.resource.sys.service.ISysRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * <p>
 * 系统菜单资源目录 前端控制器
 * </p>
 *
 * @author itkjb_gen
 * @since 2020-05-27
 */
@RestController
@RequestMapping("/sys/sys-menu")
@Api(value="菜单相关接口",tags={"资源菜单相关接口"})
public class SysMenuController extends BaseController<SysMenuModel,ISysMenuService> {

    @Autowired
    ISysRoleService sysRoleService;

    /**
     * 获取系统菜单资源目录信息
     * @param param
     * @param request
     * @param response
     * @return
     */
    @GetMapping
    @ApiOperation(value="获取系统菜单资源目录列表",notes="可分页")
    @PreAuthorize("hasAnyAuthority('SysMenu','SysMenu:query') || hasRole('"+ BaseConstants.ADMINISTRATOR_ROLE_CODE +"') ")
    public BaseResult<IPage<SysMenuModel>> page(BaseDto param, SysMenuModel model, HttpServletRequest request, HttpServletResponse response){
        BaseResult<IPage<SysMenuModel>> res = new BaseResult<>();
        SearchModel<SysMenuModel> searchModel= QueryUtil.build(param,model);
        IPage<SysMenuModel> data = this.baseService.page(searchModel);
        res = res.toSuccess();
        res.setData(data);
        return res;
    }

    /**
     * @param param 查询通用参数
     * @param model 特定条件参数
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/list")
    @ApiOperation(value="获取系统菜单资源目录列表",notes="分页参数不可用")
    @PreAuthorize("hasAnyAuthority('SysMenu','SysMenu:query') || hasRole('"+ BaseConstants.ADMINISTRATOR_ROLE_CODE +"') ")
    public BaseResult<List<SysMenuModel>> list(BaseDto param, SysMenuModel model, HttpServletRequest request, HttpServletResponse response){
        BaseResult<List<SysMenuModel>> res = new BaseResult<>();
        // 名称查询的时候将 parendId 置空
        if(StringUtils.isNotBlank(model.getTitle())){
            model.setParentId(null);
        }
        SearchModel<SysMenuModel> searchModel= QueryUtil.build(param,model);
        List<SysMenuModel> data = this.baseService.list(searchModel);
        res = res.toSuccess();
        res.setData(data);
        return res;
    }


    /**
     * 用户登录后的初始化，不需要权限
     * @param param 查询通用参数
     * @param model 特定条件参数
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/init")
    @ApiOperation(value="登陆后，菜单初始化",notes="一次性返回结果",tags = "用户自身相关接口")
    public BaseResult<List<SysMenuVO>> init(BaseDto param, SysMenuModel model, HttpServletRequest request, HttpServletResponse response){
        BaseResult<List<SysMenuVO>> res = new BaseResult<>();
        model.setStatus(1);
        List<SysMenuVO> data = null;
        if(isAdmin()){
            data = this.baseService.treeWithButton(model);
            res = res.toSuccess();
        }else {
            RequestUserInfoModel userInfoModel = RequestUserInfoUtil.getRequestUserInfoModel();
            List<SysMenuModel> menuPermissions = this.baseService.findMenuPermissionByUserId(userInfoModel.getUserId());
            if(menuPermissions !=null && menuPermissions.size()>0){
                model.setIds(new ArrayList<>(menuPermissions.size()));
                for (SysMenuModel menuPermission : menuPermissions) {
                    model.getIds().add(menuPermission.getId());
                }
            /*data = this.baseService.tree(model);
            List<SysMenuModel> buttons = this.baseService.getButtons(model);
            this.baseService.treeWithButton(data,buttons);*/
                data = this.baseService.treeWithButton(model);
                res = res.toSuccess();
            }else{
               res.setMsg("您暂未获得任何操作权限，请联系管理员进行授权后访问");
            }

        }
        res.setData(data);
        return res;
    }

    /**
     * 判断是否是管理员
     * @return
     */
    protected boolean isAdmin(){
        boolean isAdmin = false;
        RequestUserInfoModel userInfoModel = RequestUserInfoUtil.getRequestUserInfoModel();
        List<SysRoleModel> roleModels = sysRoleService.findRoleIdAndCodeByUserId(userInfoModel.getUserId());
        if(roleModels!=null && roleModels.size()>0){
            for (SysRoleModel roleModel : roleModels) {
                if(BaseConstants.ADMINISTRATOR_ROLE_CODE.equals(roleModel.getCode())){
                    isAdmin = true;
                    break;
                }
            }
        }
        return isAdmin;
    }

    @GetMapping("/tree")
    @ApiOperation(value="树形菜单",notes="一次性返回结果,默认不包含按钮信息，需要的话，menuType=7")
    @PreAuthorize("hasAnyAuthority('SysMenu','SysMenu:query') || hasRole('"+ BaseConstants.ADMINISTRATOR_ROLE_CODE +"') ")
    public BaseResult<List<SysMenuVO>> tree(BaseDto param, SysMenuModel model, HttpServletRequest request, HttpServletResponse response){
        BaseResult<List<SysMenuVO>> res = new BaseResult<>();
        if(model.getMenuType() == null || model.getMenuType() == 0){
            model.setMenuType(SysConstants.MenuType.DIR.getKey()+SysConstants.MenuType.MENU.getKey());
        }
        model.setStatus(1);
        model.setIsDel(false);
        List<SysMenuVO> data = null;
        if(isAdmin()){
            data = this.baseService.tree(model);
            res = res.toSuccess();
        }else {
            RequestUserInfoModel userInfoModel = RequestUserInfoUtil.getRequestUserInfoModel();
            List<SysMenuModel> menuPermissions = this.baseService.findMenuPermissionByUserId(userInfoModel.getUserId());
            if(menuPermissions !=null && menuPermissions.size()>0){
                model.setIds(new ArrayList<>(menuPermissions.size()));
                for (SysMenuModel menuPermission : menuPermissions) {
                    model.getIds().add(menuPermission.getId());
                }
                data = this.baseService.tree(model);
                res = res.toSuccess();
            }
        }
        res.setData(data);
        return res;
    }

    /**
     * 新增系统菜单资源目录
     * @param param
     * @param request
     * @param response
     * @return
     */
    @PostMapping
    @ApiOperation(value="新增系统菜单资源目录",notes="")
    @PreAuthorize("hasAnyAuthority('SysMenu:add') || hasRole('"+ BaseConstants.ADMINISTRATOR_ROLE_CODE +"') ")
    public BaseResult<SysMenuModel> add(@Valid @RequestBody SysMenuModel param, HttpServletRequest request, HttpServletResponse response){
        BaseResult<SysMenuModel> res = new BaseResult<>();
        // 保存菜单或目录
        if(param.getMenuType() == SysConstants.MenuType.DIR.getKey() ||
                param.getMenuType() == SysConstants.MenuType.MENU.getKey()){
            if(StringUtils.isBlank(param.getParentId())){
                param.setParentId(SysConstants.DEFAULT_TOP_PARENT_ID);
            }
            if(this.baseService.save(param)){
                if(StringUtils.isBlank(param.getPermission())){
                    param.setPermission(param.getCode());
                }
                res = res.toSuccess().setData(param);
                this.baseService.saveAutoAddButtonMenu(param);
            }
        }else{
            if(StringUtils.isBlank(param.getParentId()) ||
                    StringUtils.isBlank(param.getCode()) || StringUtils.isBlank(param.getTitle())){
                res.setMsg("参数缺失");
            }else{
                if(this.baseService.saveButton(param)){
                    res.toSuccess().setData(param);
                }
            }

        }
        return res;
    }

    /**
     * 获取详情
     * @param id
     * @param response
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation(value="获取详情",notes="")
    @ApiParam(name = "id",type = "Serializable",required = true)
    @PreAuthorize("hasAnyAuthority('SysMenu:info') || hasRole('"+ BaseConstants.ADMINISTRATOR_ROLE_CODE +"') ")
    public BaseResult<SysMenuModel> info(@PathVariable("id") Serializable id, HttpServletResponse response){
        return super.info(id);
    }

    /**
     * 修改系统菜单资源目录
     * 注意：菜单更新，不会跟新子集的权限，如果需要都跟新，需要手动调用一遍子集的更新接口
     * @param param
     * @param request
     * @param response
     * @return
     */
    @PutMapping
    @ApiOperation(value="修改系统菜单资源目录",notes="注意：菜单更新，不会跟新子集的权限，如果需要都跟新，需要手动调用一遍子集的更新接口")
    @PreAuthorize("hasAnyAuthority('SysMenu:edit') || hasRole('"+ BaseConstants.ADMINISTRATOR_ROLE_CODE +"') ")
    public BaseResult<SysMenuModel> edit(@RequestBody SysMenuModel param,HttpServletRequest request, HttpServletResponse response){
        BaseResult<SysMenuModel> res = new BaseResult<>();
        if(param == null || param.getId() ==null){
            res.setMsg("参数缺失");
        return res;
        }else if(param.getId().equals(param.getParentId())){
            res.setMsg("不能指定自身为上级菜单");
            return res;
        }else if(param.getMenuType() != null && param.getMenuType() != SysConstants.MenuType.BUTTON.getKey() &&
                StringUtils.isNotBlank(param.getParentId()) &&
                !SysConstants.DEFAULT_TOP_PARENT_ID.equals(param.getParentId())){
            List<String> subIds = this.baseService.getSubIds(param.getId());
            if(subIds !=null && subIds.size()>0 && subIds.contains(param.getParentId())){
                res.setMsg("不能指定自身的下级为上级菜单");
                return res;
            }
        }else if(param.getMenuType()!=null && SysConstants.MenuType.BUTTON.getKey() == param.getMenuType()){
            // 如果 是按钮类型的,  重置权限属性
            SysMenuModel byId = this.baseService.getById(param.getParentId());
            if(byId != null){
                param.setPermission(byId.getPermission()+":"+param.getCode());
            }
        }
        if(this.baseService.updateById(param)){
            res = res.toSuccess();
        }else {
            res.setMsg(SysConstants.UPDATE_ERROR_MESSAGE);
        }
        return res;
    }

    /**
     * 删除系统菜单资源目录
     * @param ids
     * @param request
     * @param response
     * @return
     */
    @DeleteMapping
    @ApiOperation(value="删除系统菜单资源目录",notes="数组")
    @PreAuthorize("hasAnyAuthority('SysMenu:del') || hasRole('"+ BaseConstants.ADMINISTRATOR_ROLE_CODE +"') ")
    public BaseResult<SysMenuModel> delete(@RequestBody String[] ids, HttpServletRequest request, HttpServletResponse response){
        BaseResult<SysMenuModel> res = new BaseResult<>();
        if(ids==null || ids.length<=0 ){
            res.setMsg("参数缺失");
        }else{
            List<String> idLists = Arrays.asList(ids);
            boolean b = this.baseService.deleteByLogic(idLists);
            if(b){
                res = res.toSuccess();
            }else{
                res.setMsg("操作失败");
            }
        }
        return res;
    }

}

